package org.jeecg.modules.demo.sopayorder.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.api.dto.message.TemplateMessageDTO;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.demo.advancesReceived.entity.YxAdvancesReceived;
import org.jeecg.modules.demo.advancesReceived.mapper.YxAdvancesReceivedMapper;
import org.jeecg.modules.demo.puInvoice.entity.PuInvoice;
import org.jeecg.modules.demo.puInvoice.mapper.PuInvoiceMapper;
import org.jeecg.modules.demo.sopayorder.entity.SoPayorder;
import org.jeecg.modules.demo.sopayorder.mapper.SoPayorderMapper;
import org.jeecg.modules.demo.sopayorder.service.ISoPayorderService;
import org.jeecg.modules.demo.util.BigDecimalUtil;
import org.jeecg.modules.demo.utils.generateOddUtil;
import org.jeecg.modules.demo.yxqcyfOrder.entity.YxQcyfOrder;
import org.jeecg.modules.demo.yxqcyfOrder.mapper.YxQcyfOrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: so_payorder
 * @Author: jeecg-boot
 * @Date:   2021-12-18
 * @Version: V1.0
 */
@Service
public class SoPayorderServiceImpl extends ServiceImpl<SoPayorderMapper, SoPayorder> implements ISoPayorderService {
    @Resource
    private SoPayorderMapper soPayorderMapper;
    @Resource
    private PuInvoiceMapper puInvoiceMapper;
    @Resource
    private YxAdvancesReceivedMapper yxAdvancesReceivedMapper;
    @Resource
    private YxQcyfOrderMapper yxQcyfOrderMapper;

    @Autowired
    private ISysBaseAPI sysBaseAPI;

    private static final String TITLE = "单据审核";


    private String getMessage(String name,String date) {
        String str ="由【"+name+"】于【"+date+"】发起的普通付款单需要您的审核，请及时查看！";
        return str;
    }

    @Override
    public IPage<SoPayorder> pageList(Page<SoPayorder> page, QueryWrapper<SoPayorder> queryWrapper) {
        return soPayorderMapper.getPageList(page, queryWrapper);
    }

    @Override
    public Map<String,Double> getNumAndMoney(){
        return soPayorderMapper.getNumAndMoney();
    }
    @Override
    public Map<String,Double> getSktOrderNumAndMoney(){
        return soPayorderMapper.getSktOrderNumAndMoney();
    }
    @Override
    public String getMaxCode(){
        return soPayorderMapper.getMaxCode();
    }

    @Override
    public double getSumJe(String str){
        return soPayorderMapper.getSumJe(str);
    }
    @Override
    public double getQCyfSumJe(String str){
        return soPayorderMapper.getQCyfSumJe(str);
    }
    @Override
    public SoPayorder getBySopNo(String no){
        return  soPayorderMapper.getBySopNo(no);
    }

    @Override
    public List<String> selectByPuiNo(String puiNo){
        return soPayorderMapper.selectByPuiNo(puiNo);
    }

    @Override
    public List<SoPayorder> getByQcyfOrder(String order){
        return soPayorderMapper.getByQcyfOrder(order);
    }


    @Override
    @Transactional
    public boolean checkSoPayOrder(SoPayorder soPayorder){
        try{
            soPayorder.setShenhe(1);
            soPayorder.setShTime(new Date());
            soPayorderMapper.updateById(soPayorder);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }

    @Override
    @Transactional
    public boolean delPayOrder(SoPayorder soPayorder){
        try{
            if(soPayorder.getPuiNo()!=null){
                Double money = soPayorder.getSfamount().doubleValue();
                PuInvoice puInvoice = puInvoiceMapper.getByNumber(soPayorder.getPuiNo());
                puInvoice.setYjjine(new BigDecimal(BigDecimalUtil.add(money,puInvoice.getYjjine().doubleValue())));
                puInvoice.setSupamount(new BigDecimal(BigDecimalUtil.sub(puInvoice.getSupamount().doubleValue(),money)));
                puInvoiceMapper.updateById(puInvoice);
            }else{
                YxQcyfOrder yxQcyfOrder = yxQcyfOrderMapper.getByOrder(soPayorder.getQcyfNo());
                yxQcyfOrder.setSurplusJine(new BigDecimal(BigDecimalUtil.add(soPayorder.getSfamount().doubleValue(),yxQcyfOrder.getSurplusJine().doubleValue())));
                yxQcyfOrderMapper.updateById(yxQcyfOrder);
            }
            if(soPayorder.getReceiptNumber()!=null){
                YxAdvancesReceived advancesReceived =  addYf(soPayorder);
                yxAdvancesReceivedMapper.updateById(advancesReceived);
                SoPayorder dkorder = soPayorderMapper.getBySopNo(soPayorder.getYfdkorder());
                soPayorderMapper.deleteById(dkorder.getId());
                List<SoPayorder> soPayorders = soPayorderMapper.getListByYfOrder(soPayorder.getReceiptNumber());
                if(!soPayorders.isEmpty()){
                    for (SoPayorder payorder : soPayorders) {
                        payorder.setYfsyje(advancesReceived.getSupAmount());
                        soPayorderMapper.updateById(payorder);
                    }
                }
            }
            soPayorderMapper.deleteById(soPayorder.getId());
            return true;
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }
    private YxAdvancesReceived addYf(SoPayorder soPayorder) throws Exception {
        YxAdvancesReceived advancesReceived = yxAdvancesReceivedMapper.getByReceiptNumber(soPayorder.getReceiptNumber());
        Double sup = advancesReceived.getSupAmount().doubleValue();
        Double amount = soPayorder.getYfuseje().doubleValue();
        advancesReceived.setSupAmount(new BigDecimal(org.jeecg.modules.demo.utils.BigDecimalUtil.add(sup, amount)));
        return advancesReceived;
    }
    @Override
    @Transactional
    public boolean editPayOrder(SoPayorder soPayorder,String precode){
        try{
            SoPayorder soPayorder1 = soPayorderMapper.selectById(soPayorder.getId());
            if(soPayorder1.getReceiptNumber()!=null){
                YxAdvancesReceived advancesReceived =  addYf(soPayorder1);
                yxAdvancesReceivedMapper.updateById(advancesReceived);
                SoPayorder dkorder = soPayorderMapper.getBySopNo(soPayorder.getYfdkorder());
                soPayorderMapper.deleteById(dkorder.getId());
                List<SoPayorder> soPayorders = soPayorderMapper.getListByYfOrder(soPayorder.getReceiptNumber());
                if(!soPayorders.isEmpty()){
                    for (SoPayorder payorder : soPayorders) {
                        payorder.setYfsyje(advancesReceived.getSupAmount());
                        soPayorderMapper.updateById(payorder);
                    }
                }
            }
            if(soPayorder.getReceiptNumber()!=null){
                SoPayorder dkPayOrder = getSoPayOrder(soPayorder,precode);
                soPayorderMapper.insert(dkPayOrder);
                soPayorder.setYfdkorder(dkPayOrder.getSopNo());
                YxAdvancesReceived advancesReceived= updateAdvancesReceived(soPayorder);
                soPayorder.setYfsyje(advancesReceived.getSupAmount());
                yxAdvancesReceivedMapper.updateById(advancesReceived);
                List<SoPayorder> soPayorders = soPayorderMapper.getListByYfOrder(soPayorder.getReceiptNumber());
                if(!soPayorders.isEmpty()){
                    for (SoPayorder payorder : soPayorders) {
                        payorder.setYfsyje(advancesReceived.getSupAmount());
                        soPayorderMapper.updateById(payorder);
                    }
                }
            }else{
                soPayorder.setReceiptNumber(null);
                soPayorder.setYfsyje(null);
                soPayorder.setYfuseje(null);
                soPayorder.setYfdkorder(null);
            }
           if(soPayorder.getPuiNo()!=null){
               Double money = soPayorder.getSfamount().doubleValue();
               Double m = soPayorder1.getSfamount().doubleValue();
               PuInvoice puInvoice = puInvoiceMapper.getByNumber(soPayorder.getPuiNo());
               Double cha;
               if(m>money){
                   cha = BigDecimalUtil.sub(m,money);
                   puInvoice.setYjjine(new BigDecimal(BigDecimalUtil.add(puInvoice.getYjjine().doubleValue(),cha)));
                   puInvoice.setSupamount(new BigDecimal(BigDecimalUtil.sub(puInvoice.getSupamount().doubleValue(),cha)));
               }else{
                   cha = BigDecimalUtil.sub(money,m);
                   puInvoice.setYjjine(new BigDecimal(BigDecimalUtil.sub(puInvoice.getYjjine().doubleValue(),cha)));
                   puInvoice.setSupamount(new BigDecimal(BigDecimalUtil.add(puInvoice.getSupamount().doubleValue(),cha)));
               }
               soPayorder.setShTime(null);
               puInvoiceMapper.updateById(puInvoice);
           }else{
               YxQcyfOrder yxQcyfOrder = yxQcyfOrderMapper.getByOrder(soPayorder.getQcyfNo());
               yxQcyfOrder.setSurplusJine(new BigDecimal(BigDecimalUtil.add(soPayorder1.getSfamount().doubleValue(),yxQcyfOrder.getSurplusJine().doubleValue())));
               yxQcyfOrder.setSurplusJine(new BigDecimal(BigDecimalUtil.sub(yxQcyfOrder.getSurplusJine().doubleValue(),soPayorder.getSfamount().doubleValue())));
               yxQcyfOrderMapper.updateById(yxQcyfOrder);
           }
            soPayorderMapper.updateById(soPayorder);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }
    private YxAdvancesReceived updateAdvancesReceived(SoPayorder soPayorder) throws Exception {
        YxAdvancesReceived advancesReceived = yxAdvancesReceivedMapper.getByReceiptNumber(soPayorder.getReceiptNumber());
        Double sup = advancesReceived.getSupAmount().doubleValue();
        Double amount = soPayorder.getYfuseje().doubleValue();
        Double supamount = BigDecimalUtil.sub(sup, amount);
        advancesReceived.setSupAmount(supamount <= 0?new BigDecimal(0):new BigDecimal(supamount));
        return advancesReceived;

    }
    @Override
    @Transactional
    public boolean addSoPayOrder(SoPayorder soPayorder,String precode){
        try{
            if(soPayorder.getPuiNo()!=null){
                List<SoPayorder> payorders = soPayorderMapper.getListByPuiNo(soPayorder.getPuiNo());
                PuInvoice puInvoice = puInvoiceMapper.getByNumber(soPayorder.getPuiNo());
                if(payorders.isEmpty()){
                    Double yj = puInvoice.getYjjine().doubleValue();
                    Double sj = soPayorder.getSfamount().doubleValue();
                    puInvoice.setYjjine(new BigDecimal(BigDecimalUtil.sub(yj, sj)));
                    puInvoice.setSupamount(new BigDecimal(BigDecimalUtil.add(puInvoice.getSupamount().doubleValue(),soPayorder.getSfamount().doubleValue())));
                    puInvoiceMapper.updateById(puInvoice);
                }else{
                    double sumJe = soPayorderMapper.getSumJe(soPayorder.getPuiNo());
                    Double yj = puInvoice.getYjjine().doubleValue();
                    Double sj = soPayorder.getSfamount().doubleValue();
                    puInvoice.setYjjine(new BigDecimal(BigDecimalUtil.sub(yj, sj)));
                    puInvoice.setSupamount(new BigDecimal(BigDecimalUtil.add(sumJe,sj)));
                    puInvoiceMapper.updateById(puInvoice);
                }
            }else{
                YxQcyfOrder yxQcyfOrder = yxQcyfOrderMapper.getByOrder(soPayorder.getQcyfNo());
                yxQcyfOrder.setSurplusJine(new BigDecimal(BigDecimalUtil.sub(yxQcyfOrder.getSurplusJine().doubleValue(),soPayorder.getSfamount().doubleValue())));
                yxQcyfOrderMapper.updateById(yxQcyfOrder);
            }
            if(soPayorder.getReceiptNumber()!=null){
                SoPayorder dkPayOrder = getSoPayOrder(soPayorder,precode);
                soPayorderMapper.insert(dkPayOrder);
                soPayorder.setYfdkorder(dkPayOrder.getSopNo());
                YxAdvancesReceived advancesReceived= updateAdvancesReceived(soPayorder);
                yxAdvancesReceivedMapper.updateById(advancesReceived);
                soPayorder.setYfsyje(advancesReceived.getSupAmount());
                List<SoPayorder> soPayorders = soPayorderMapper.getListByYfOrder(soPayorder.getReceiptNumber());
                if(!soPayorders.isEmpty()){
                    for (SoPayorder payorder : soPayorders) {
                        payorder.setYfsyje(advancesReceived.getSupAmount());
                        soPayorderMapper.updateById(payorder);
                    }
                }
            }else{
                soPayorder.setReceiptNumber(null);
                soPayorder.setYfsyje(null);
                soPayorder.setYfuseje(null);
                soPayorder.setYfdkorder(null);
            }
            soPayorder.setBusType(0);
            soPayorder.setShTime(null);
            soPayorderMapper.insert(soPayorder);
            LoginUser user = sysBaseAPI.getUserById(soPayorder.getPoStaff());
            TemplateMessageDTO templateMessageDTO = new TemplateMessageDTO();
            templateMessageDTO.setFromUser("管理员");
            templateMessageDTO.setToUser(soPayorder.getSaleman()+",");
            templateMessageDTO.setTitle(TITLE);
            templateMessageDTO.setTemplateCode("order");
            Map<String, String> templateParam = new HashMap<>();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date= simpleDateFormat.format(new Date());
            templateParam.put("ts_date",date);
            templateParam.put("ts_content",getMessage(user.getRealname(),date));
            templateParam.put("checkOrder",soPayorder.getSopNo());
            templateParam.put("cd_url","/sopayorder/soPayorder/list");
            templateMessageDTO.setTemplateParam(templateParam);
            sysBaseAPI.sendTemplateAnnouncement(templateMessageDTO);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }
    private SoPayorder getSoPayOrder(SoPayorder payorder,String precode) {
        String str = soPayorderMapper.getMaxCode();
        Map<String, String> map = new HashMap<>();
        map.put("maxCode",str==null?null:str);
        String name = precode+"DK_";
        String resultCode = generateOddUtil.createCode(map, name);
        SoPayorder soPayorder = new SoPayorder();
        soPayorder.setShanchu(0);
        soPayorder.setShenhe(0);
        soPayorder.setBusType(2);
        soPayorder.setReceiptNumber(payorder.getReceiptNumber());
        soPayorder.setSopNo(resultCode);
        soPayorder.setPuiNo(payorder.getPuiNo());
        soPayorder.setSopDate(new Date());
        soPayorder.setSfamount(payorder.getYfuseje());
        soPayorder.setPoStaff(payorder.getPoStaff());
        soPayorder.setDepartment(payorder.getDepartment());
        soPayorder.setSaleman(payorder.getSaleman());
        soPayorder.setJsfs(2);
        soPayorder.setPoOrder(payorder.getPoOrder());
        soPayorder.setFkjine(new BigDecimal(0.000));
        soPayorder.setTradecode(payorder.getTradecode()!=null?payorder.getTradecode():null);
        soPayorder.setShTime(null);
        return soPayorder;
    }

}
